/*
	libidxp initiator example:
		This is a simple example of creating a libidxp initiator using
		libidxp library. It shows how to use some of the features included
		in this version of the library.
*/


/* Library inclusion */
#include <libidxp.h>

/* Custom function called automatically by the library through the use of "idxp_custom" family functions (see below..) */
/* In this type of function you can handle the frame and its payload using idxp_frame_get_payload(frame) */
bool CUSTOM_INRECEIVE_FUNCTION(IdxpConnection *connection,IdxpChannel *channel,IdxpFrame *frame, axlPointer data){
	printf("Custom Business logic\n");
	printf("PAYLOAD:%s\n",idxp_frame_get_payload(frame));
	return true;
}



int main(int argc, char **argv){
	/* Declaration of structures used by libidxp such as connection and channel pointers, frame pointer and so on .. */
	IdxpConnection *connection = NULL,*connection2 = NULL;
	IdxpChannel *channel,*channel2;
	IdxpFrame *frame;
	char *msg;


	/* Initialization MACRO for initiator side, it must be present before any other libidxp function call!!! */
	IDXPLIB_INITIATOR


	/* Idxp custom family function telling the library to make a call to 
	   CUSTOM_INRECEIVE_FUNCTION everytime a message is received and the 
	   channel role is ALERT/CLIENT 				    */
	idxp_custom_alert_client_set(CUSTOM_INRECEIVE_FUNCTION);


	/* if at least one argument is passed to the program, that argument will be used as configuration file path
	and passed to idxp_configuration_load() */
	(argc>1) ? idxp_configuration_load(argv[1],NULL) : idxp_configuration_load("Insert here the default configuration file path",NULL);


	/* Starting 2 connections to 127.0.0.1/44441, using credentials provided from configuration file previously loaded */
	connection=idxp_connection_start(connection,"127.0.0.1","44441",idxp_configuration_get("usr",NULL),idxp_configuration_get("pw",NULL));
	connection2=idxp_connection_start(connection2,"127.0.0.1","44441",idxp_configuration_get("usr",NULL),idxp_configuration_get("pw",NULL));


	/* Opening channel n 1 over the first connection, type and role used in the channel are ALERT and CLIENT */
	channel=idxp_channel_new(connection,1,"localhost",0,"client",idxp_configuration_get("uri",NULL),idxp_configuration_get("fqdn",NULL),"alert");


	/* Opening channel n 2 over the second connection, type and role used in the channel are HEARTBEAT and SERVER */
	/* It means that after the channel creation, initiator side creates a new thread that will handle heartbeat reception. */
	channel2=idxp_channel_new(connection,2,"localhost",0,"server",idxp_configuration_get("uri",NULL),idxp_configuration_get("fqdn",NULL),"heartbeat");

	getchar();
	
	/* This function creates and sends a new greeting over channel2, handling all the idxp greeting handshake and holding until the operation is over */
	/* In this case channel2 is switching from a HEARTBEAT channel type acting as server to an ALERT channel type with client role; it means that you */
	/* can easily switch from every channel type to another, without worrying about the previous channel role */
	idxp_greeting_send_and_wait(channel2,"client","alert",true);


	/* Sending messages ... */
	/* This is a handmade heartbeat creation, since idmef-heartbeat is a IDMEF-Message, you can send it through an alert channel */
	msg=idmef_create_heartbeat("msgId",idxp_configuration_get("analyzer_id",NULL),100,NULL,NULL);

	/* Once the message is created, it's time to send it to the opposite side !!! */
	/* You can send it through the chosen channel and let the Frame Receive handle the reply, so these 2 are non-blocking calls */
	idxp_channel_send_msg(channel,msg);
	idxp_channel_send_msg(channel2,msg);


	/* Or you can send the message and directly handle the related reply just after its reception */
	frame=idxp_channel_send_msg_and_wait(channel,msg);
	printf("[REPLY Payload]: %s\n",(char*)vortex_frame_get_payload(frame));
	/* NOTE that you have to free the frame by yourself if you choose this type of function */	
	vortex_frame_free(frame);


	/* Last but not least, you can BROADCAST the message through every channel of the same type and with the same role */
	/* This means that, with just one call you send the message through both "channel" and "channel2" because both have */
	/* the same streamtype (alert) and the same role (client). IDXPROLE_AC stands for AlertClient. */
	idxp_broadcast_send_message(IDXPROLE_AC,msg);


	/* The function used for creating the heartbeat message allocates memory, that MUST be freed */
	free(msg);
	getchar();

	/* Now we have to close channels previously created .. */
	idxp_channel_close(channel);
	idxp_channel_close(channel2);


	/* ... and the connections */
	vortex_connection_close(connection);
	vortex_connection_close(connection2);


	/* This function MUST be called in order to close the program properly and deallocate libidxp environment */
	idxp_exit();

	printf("End of Initiator Example\n");

	return 1;
}

